﻿<cfscript>

/** 
* Security Frameworks - groupFilter
* 
* @extends "MachII.framework.EventFilter"
* 
* @displayname "acadmicManager.filters.security.groupFilter" 
* @hint "Security Frameworks - groupFilter" 
* 
* @Output false
* 
* @depends "securityAdvice, sessionAdvice, casAdvice, tagLocationHelper, tagHeaderHelper"
*/ 

component {
	
	/**
	* @hint "Configures this filter as part of the Mach-II framework"
	* 
	* @Output false
	*/
	public void function configure() {} 
	
	/**
	* @hint "Filters event and returns a boolean to Mach-II indicating whether or not the event queue should proceed.  If not, the event queue is cleared and a new event is announced."
	* 
	* @Output false
	* 
	* @event "MachII Event Object"
	* @eventContext "MachII EventContext Object"
	*/
	public boolean function filterEvent ( required MachII.framework.Event event, required MachII.framework.EventContext eventContext ) {
		
		var casAdvice = getcasAdvice();
		var sessionAdvicer = getsessionAdvice();
		
		var logFactory = getProperty("serviceFactory").getBean("logFactory");
		
		var router = gettagLocationHelper();
		var header = gettagHeaderHelper();
		
		var ticketId = event.getArg("ticket");
		
		var sql = "";
		var queryObj = "";
		
		/* 第一步 首先检查内部的认证信息是否存在 */
		if ( sessionAdvice.isUserAuthorized() ) {
			/* 如果本地 session 已经存在的话 */
			if ( sessionAdvice.isUserInAnyAuthorizedGroups( getParameter("authorizedGroup") ) ) {
				/* 验证用户是否归属于限定的用户组 */
				
				/* 继续执行 event 请求 */
				return true;
			}
			else {
				/* 如果用户没有得到适合的授权, 则提示用户越权访问 */
				announceEvent("accessDenide");
				
				/* 结束 event 请求 */
				return false;
			}
		}
		else {
			
			/* 如果没有本地 session , 则需要检查 CAS 服务认证 */
			
			if ( len(ticketId) ) {
				
				/* 使用 ST-UUID 尝试读取当前用户 */
				var username = casAdvice.getUserId( ticketId );
				
				if ( len(username) ) {
					
					
					/* 如果存在　CAS　认证的用户名 则进行本地认证 */
									
					/* 调用用户权限分配数据库 */
					sql = "SELECT user_id FROM t_user WHERE user_login = :username ";

					queryObj = new Query( datasource=application.dnsSlave );
					queryObj.addParam( name="username", value=username, cfsqltype="cf_sql_varchar" );
			
					var rs_user = queryObj.execute( sql=sql ).getResult();
					
					
					if ( rs_user.recordCount eq 0 ) {
						
						/* 如果cas认证信息没有对应的 学号 或 教工号 对应 */
						/* 提示用户越权访问 */
						announceEvent("accessDenide");
						
						/* 结束 event 请求 */
						return false;
					}
					else {
						
						/* 如果cas认证信息在系统中有对应的登记记录 */
						sql = "SELECT group_id FROM t_groupuser WHERE user_id = :username ";
						
						queryObj = new Query( datasource=application.dnsSlave );
						queryObj.addParam( name="username", value=rs_user.user_id, cfsqltype="cf_sql_varchar" );
						
						var rs_usergroup = queryObj.execute( sql=sql ).getResult();
						
						var groupList = "";
						
						for( var i=1; i LTE rs_usergroup.recordCount; i++ ){
							groupList = listAppend( groupList, rs_usergroup["group_id"][i], "," );
						}
						
						/* 生成用户相关属性 */
						var userProps = structNew();
						
						/*
							P001	教师
							P002	学生
						*/
						
						/* 教师相关属性 */
						if ( listFind( groupList, "P001", "," ) ) {
				
							sql = "SELECT tch_name, institute_id FROM t_teacher WHERE tch_id = :teacherId";
				
							queryObj = new Query( datasource=application.dnsSlave );
							queryObj.addParam( name="teacherId", value=rs_user.user_id, cfsqltype="cf_sql_varchar" );
				
							var rs_teacher = queryObj.execute( sql=sql ).getResult();
							
							logFactory.writeLog("1","教师 " & rs_teacher.tch_name & "(" & rs_user.user_id & ") 登录系统", rs_user.user_id);
							
							if ( rs_teacher.recordCount ) {
								
								structInsert( userProps, "userName", rs_teacher.tch_name, true);
								structInsert( userProps, "teacherDepartment", rs_teacher.institute_id, true);
							
							}
				
						}
						
						/* 学生相关属性 */
						if ( listFind( groupList, "P002", "," ) ) {
							
							sql = "SELECT 
										t_student.stu_name, t_student.sbj_direction, t_student.stu_sex, 
										t_student.cls_id, 
										t_student_status.student_prop 
									FROM t_student 
										INNER JOIN t_student_status on t_student_status.stu_id = t_student.stu_id 
									WHERE 
										t_student.stu_id = :studentId";
				
							queryObj = new Query( datasource=application.dnsSlave );
							queryObj.addParam( name="studentId", value=rs_user.user_id, cfsqltype="cf_sql_varchar" );
				
							var rs_student = queryObj.execute( sql=sql ).getResult();
							
							var rs_class = queryNew("");
						
							
							if( rs_student.cls_id neq ""){
								
								sql = "SELECT 
											t_class.grade, 
											t_subject.sbj_id, t_subject.institute_id 
										FROM t_class 
											INNER JOIN t_subject ON t_subject.sbj_id = t_class.sbj_id 
										WHERE 
											t_class.cls_id = :classId";
					
								queryObj = new Query( datasource=application.dnsSlave );
								queryObj.addParam( name="classId", value=rs_student.cls_id, cfsqltype="cf_sql_varchar" );
					
								rs_class = queryObj.execute( sql=sql ).getResult();
							}
							
							
							logFactory.writeLog("2","学生 " & rs_student.stu_name & "(" & rs_user.user_id & ") 登录系统", rs_user.user_id);
							
							if ( rs_student.recordCount ) {
								
								structInsert( userProps, "userName", rs_student.stu_name, true );
								structInsert( userProps, "studentClass", rs_student.cls_id, true );
								structInsert( userProps, "studentSubDir", rs_student.sbj_direction, true );
								structInsert( userProps, "studentProps", rs_student.student_prop & "E", true );
								structInsert( userProps, "studentSex", rs_student.stu_sex, true );
								
							}
							
							if( rs_class.recordCount ){
								structInsert( userProps, "studentGrade", rs_class.grade, true );
								structInsert( userProps, "studentSubject", rs_class.sbj_id, true );	
								structInsert( userProps, "studentDepartment", rs_class.institute_id, true );
							}
							
							
							/* 辅修学生专业和方向 */
							sql = "SELECT sbj_id, sbj_direction, grade FROM t_student_secsubject WHERE stu_id = :studentId";
							
							queryObj = new Query( datasource=application.dnsSlave );
							queryObj.addParam( name="studentId", value=rs_user.user_id, cfsqltype="cf_sql_varchar" );
				
							var rs_student_assist = queryObj.execute( sql=sql ).getResult();
							
							if ( rs_student_assist.recordCount ) {
								
								structInsert( userProps, "studentAssistSubject", rs_student_assist.sbj_id, true );
								structInsert( userProps, "studentAssistSubDir", rs_student_assist.sbj_direction, true );
								structInsert( userProps, "studentAssistGrade", rs_student_assist.grade, true );
								
							}
				
							/* 双学位专业和方向 */
							sql = "SELECT sbj_id, sbj_direction, grade FROM t_student_secdegree WHERE stu_id = :studentId";
							
							queryObj = new Query( datasource=application.dnsSlave );
							queryObj.addParam( name="studentId", value=rs_user.user_id, cfsqltype="cf_sql_varchar" );
				
							var rs_student_second = queryObj.execute( sql=sql ).getResult();
							
							if ( rs_student_second.recordCount ) {
				
								structInsert( userProps, "studentSecondSubject", rs_student_second.sbj_id, true );
								structInsert( userProps, "studentSecondSubDir", rs_student_second.sbj_direction, true );
								structInsert( userProps, "studentSecondSubDir", rs_student_second.grade, true );
				
							}
							
						}
						
						/* 设置用户验证会话 */
						sessionAdvice.login( authUser: rs_user.user_id, authGroup: groupList, userProps: userProps );
						
						
						if ( sessionAdvice.isUserInAnyAuthorizedGroups( getParameter("authorizedGroup") ) ) {
							/* 验证用户是否归属于限定的用户组 */
							
							/* 继续执行 event 请求 */
							return true;
						}
						else {
							
							/* 如果用户没有得到适合的授权, 则提示用户越权访问 */
							announceEvent("accessDenide");
						
							/* 结束 event 请求 */
							return false;
						}
						
						
					}

				}
				
			}
			
			var _redirectURL = casAdvice.getLoginURL();
				
			/* 将用户重定向到服务页面 */
			header.noCache();

			router.redirect( urlAddress=_redirectURL, statusCode=301 );
			
			/* 结束 event 请求 */
			return false;
			
		}
		
		/* 结束 event 请求 */
		return false;
	}
		
}

</cfscript>